﻿using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ViewROI
{
    public class HHomMat2D
    {
        public readonly int ools = 3;

        public readonly int rows = 3;

        public float[] Elements
        {
            get
            {
                return matrix.Elements;
            }
        }

        Matrix matrix = new Matrix();
        public HHomMat2D()
        {
            matrix = new Matrix();
        }

        public HHomMat2D(float m11, float m12, float m21, float m22, float dx, float dy)
        {
            matrix = new Matrix(m11, m12, m21, m22, dx, dy);
        }
        public HHomMat2D HomMat2dInvert()
        {
            HHomMat2D mat2D = new HHomMat2D();

            mat2D.matrix = matrix.Clone();

            mat2D.matrix.Invert();

            return mat2D;
        }

        public void HomMat2dIdentity()
        {
            matrix = new Matrix(1, 0, 0, 1, 0, 0);
        }

        public HHomMat2D HomMat2dTranslate(double dx, double dy)
        {
            HHomMat2D mat2D = new HHomMat2D();

            mat2D.matrix = matrix.Clone();

            mat2D.matrix.Translate((float)(dx), (float)(dy));

            return mat2D;
        }

        public HHomMat2D HomMat2dRotateLocal(double phi)
        {
            HHomMat2D mat2D = new HHomMat2D();

            mat2D.matrix = matrix.Clone();

            mat2D.matrix.Rotate((float)(phi*180/Math.PI));

            return mat2D;
        }

        public HHomMat2D HomMat2dScaleLocal(double scaleX, double scaleY)
        {
            HHomMat2D mat2D = new HHomMat2D();

            mat2D.matrix = matrix.Clone();

            mat2D.matrix.Scale((float)scaleX, (float)scaleY);

            return mat2D;
        }

        public double AffineTransPoint2d(double x, double y, out double dstY)
        {
            System.Drawing.PointF[] points = new System.Drawing.PointF[1];
            points[0] = new System.Drawing.PointF((float)x, (float)y);
            matrix.TransformPoints(points);
            dstY = points[0].Y;
            return points[0].X;            
        }

        public List<double> AffineTransPoint2d(List<double> srcX, List<double> srcY, out List<double> dstY)
        {
            System.Drawing.PointF[] pointsA = new System.Drawing.PointF[6];

            for(int i = 0; i < srcX.Count; i++)
            {
                float x = (float)srcX[i];
                float y = (float)srcY[i];
                pointsA[i] = (new System.Drawing.PointF(x, y));
            }


            matrix.TransformPoints(pointsA);

            List<double> dx = new List<double>();
            List<double> dy = new List<double>();

            List<System.Drawing.PointF> points = pointsA.ToList();

            points.ForEach((point) => { dx.Add((float)point.X);  dy.Add((float)point.Y); });

            dstY = dy;
            return dx;
        }
        private HHomMat2D Mat2HHom()
        {
            return this;
        }

        private Matrix HHom2Mat()
        {
            matrix = new Matrix(Elements[0], Elements[1], Elements[2],
                Elements[3], Elements[4], Elements[5]);
            return matrix;
        }
    }
}
